//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#ifndef __CCAMERA_H__
#define __CCAMERA_H__

#include <display.h>
#include <camera.h>
#include <xllp_camera.h>
#include <xllp_ci.h>

//#define DEBUG_CAMERA
#ifdef DEBUG_CAMERA
#define DBGOUT(x)  x
#else
#define DBGOUT(x)
#endif

//#define _TEST_TYPE 41
#if (_TEST_TYPE == 41)      /* Test for Runtime of ISR */
    #define SAMPLETIMES 50
    extern UInt32 ul_DmaChYIsrTime[SAMPLETIMES];
    extern UInt32 ul_DmaChCbIsrTime[SAMPLETIMES];
    extern UInt32 ul_DmaChCrIsrTime[SAMPLETIMES];
#endif //_TEST_TYPE == 41

// Sensor type, now only use PO1200N
#define CAMERA_TYPE_PO1200N 1

// Quick Capture Interface FIFO
#define CIBR0_PHY 0x50000028
#define CIBR1_PHY 0x50000030
#define CIBR2_PHY 0x50000038

#define MAX_WAIT_TIME 800
#define SINGLE_DESCRIPTOR_TRANSFER_MAX  8000
#define DEFAULT_FRAMES 2
#define MAX_FRAMES 4
#define DIGITALZOOM_MAX 4

typedef enum {
    CamDrv_Status_Preview,
    CamDrv_Status_Still,
    CamDrv_Status_Video, // Reserved now
    CamDrv_Status_Unprepared,
    CamDrv_Status_Closed,
    CamDrv_Status_PreviewPaused,
    CamDrv_Status_Reserved
} CamDrv_Status;

typedef struct {
    unsigned long VideoWidth;
    unsigned long VideoHeight;
    unsigned long PhotoWidth;
    unsigned long PhotoHeight;
} CamDrv_Resolution;

// Buffer address and the corresponding descriptors
#define TRANS_CHANNELS 3
typedef struct {
    // MUST BE 8 BYTES ALIGNED
    unsigned long BufPhyAddr[MAX_FRAMES][TRANS_CHANNELS];
    unsigned long BufVirAddrKernel[MAX_FRAMES][TRANS_CHANNELS];
    unsigned long BufVirAddrUser[MAX_FRAMES][TRANS_CHANNELS];

    unsigned long DescPhyAddr[TRANS_CHANNELS];
    unsigned long DescVirAddr[TRANS_CHANNELS];

    unsigned long FrameBufSize[TRANS_CHANNELS]; // Buffer size of each FRAME
    unsigned long FrameDescNum[TRANS_CHANNELS];

    // Only used for alloc & dealloc memory, don't touch them
    unsigned int AllocBufSize;
    unsigned int AllocDescSize;
} CamDrv_DMABuffer, * PCamDrv_DMABuffer;

typedef struct {
    int PhotoResolution;
    int VideoResolution;
    int FrameRate;
    int Zoom;
    int Brightness;
    int Contrast;
    int Sharpness;
    int WhiteBalance;
    int ColorMode;
    int SceneMode;
    int Direction;
    int Flash;
    int ISO;
    int ExposureCompensation;
    int ContinuousSnap; // Number of continuous snap
} CamDrv_AppFormat;

// Context used by camera
typedef struct {
    unsigned int SensorType;

    // AppResolution is used by applications
    // DrvResolution is internally used by the driver
    CamDrv_Resolution AppResolution;
    CamDrv_Resolution DrvResolution;
    // If digital zoom is used,
    // driver resolution maybe not equal application resolution
    int DrvVideoResLevel;
    int DrvPhotoResLevel;

    unsigned int InputFormat;
    unsigned int OutputFormat;
    int DigitalZoom;

    unsigned int FrameRate;
    unsigned int UsedFrames; // Max Frames of DMA Transfer

    int DMAChannels[TRANS_CHANNELS];
    CamDrv_DMABuffer PhotoBuffer;
    CamDrv_DMABuffer PreviewBuffer;

    CamDrv_Status CaptureStatus;

//    unsigned long DigitalZoomBufferVir;
//    unsigned long DigitalZoomBufferPhy;
//    unsigned long DigitalZoomBufferSize;

    // Applications directly set these formats
    CamDrv_AppFormat AppFormat;
    CamDrv_AppFormat SavedAppFormat; // For power management

    OverlayFormat *pOverlay2;
} CamDrv_Context, *PCamDrv_Context;

// Camera Control Flow Functions
EXTERN_C ECode CamDrv_Install(PCamDrv_Context pCameraCxt);
EXTERN_C ECode CamDrv_Init(PCamDrv_Context pCameraCxt);
EXTERN_C void CamDrv_Quit(PCamDrv_Context pCameraCxt);
EXTERN_C ECode CamDrv_StartStillCapture(PCamDrv_Context pCameraCxt);
EXTERN_C ECode CamDrv_StartVideoCapture(PCamDrv_Context pCameraCxt);
EXTERN_C void CamDrv_StopVideoCapture(PCamDrv_Context pCameraCxt);
EXTERN_C void CamDrv_ReleaseFrames(PCamDrv_Context pCameraCxt);
EXTERN_C ECode CamDrv_SetBrightness(PCamDrv_Context pCameraCxt,
    int Brightness);
EXTERN_C ECode CamDrv_SetContrast(PCamDrv_Context pCameraCxt, int Contrast);
EXTERN_C ECode CamDrv_SetSharpness(PCamDrv_Context pCameraCxt, int Sharpness);
EXTERN_C ECode CamDrv_SetColorMode(PCamDrv_Context pCameraCxt,
    int ColorMode);
EXTERN_C ECode CamDrv_SetSceneMode(PCamDrv_Context pCameraCxt, int SceneMode);
EXTERN_C ECode CamDrv_SetFlash(PCamDrv_Context pCameraCxt, int Flash);
EXTERN_C ECode CamDrv_SetPhotoResolution(PCamDrv_Context pCameraCxt,
    int PhotoResolution);
EXTERN_C ECode CamDrv_SetDigitalZoom(PCamDrv_Context pCameraCxt, int zoom);
EXTERN_C ECode CamDrv_SetAppFormat(PCamDrv_Context pCameraCxt,
    unsigned int nID, int wParam, int lParam);
EXTERN_C ECode CamDrv_SetContinuousSnap(PCamDrv_Context pCameraCxt,
    int nCotinuousCount);
EXTERN_C ECode CamDrv_GetStillPhoto(PCamDrv_Context pCameraCxt,
    Camera_Photo* pPhoto);
EXTERN_C ECode CamDrv_GetAppFormat(PCamDrv_Context pCameraCxt,
    unsigned int nID, int *pwParam, int *plParam);
EXTERN_C ECode CamDrv_OpenHardware(PCamDrv_Context pCameraCxt);
EXTERN_C void CamDrv_CloseHardware(PCamDrv_Context pCameraCxt);
EXTERN_C void CamDrv_SaveFormat(PCamDrv_Context pCameraCxt);
EXTERN_C void CamDrv_ResumeFormat(PCamDrv_Context pCameraCxt);

// DMA Operations Functions
EXTERN_C void DMAAllocChannel(PCamDrv_Context pCameraCxt);
EXTERN_C ECode DMAAllocBuffer(PCamDrv_Context pCameraCxt, Boolean bPreview);
EXTERN_C void DMAFreeBuffer(PCamDrv_Context pCameraCxt, Boolean bPreview);
EXTERN_C void DMAStartTransfer(PCamDrv_Context pCameraCxt);
EXTERN_C void DMAStopTransfer(PCamDrv_Context pCameraCxt);
EXTERN_C void CamDrv_SetDefaultFormat(PCamDrv_Context pCameraCxt);

// Quick Capture Interface Functions
EXTERN_C void CIInit();
EXTERN_C void CIDeInit();
EXTERN_C void CIEnable(int dma_en);
EXTERN_C int  CIDisable(int quick);
EXTERN_C void CISetMode(XLLP_CI_MODE mode, XLLP_CI_DATA_WIDTH data_width);
EXTERN_C void CISetClock(int pclk_enable, int mclk_enable, unsigned int mclk_khz);
EXTERN_C void CISetPolarity(int pclk_sample_falling, int hsync_active_low, int vsync_active_low);
EXTERN_C void CISetFIFO(unsigned int timeout, XLLP_CI_FIFO_THRESHOLD threshold, int fifo1_enable,
                    int fifo2_enable);
EXTERN_C void CIResetFIFO();
EXTERN_C void CISetInterruptMask(unsigned int mask);
EXTERN_C void CIStartVideoCapture();
EXTERN_C void CICaptureStillImage();
EXTERN_C void CIStopVideoCapture();
EXTERN_C void CIStopStillCapture();
EXTERN_C ECode CIPrepare(PCamDrv_Context pCameraCxt);

// Sensor (PO1200N) Functions
EXTERN_C void SensorInit();
EXTERN_C ECode SensorSetCaptureFormat(PCamDrv_Context camera_context);
EXTERN_C ECode SensorStartCapture(PCamDrv_Context pCameraCxt);
EXTERN_C ECode SensorStopCapture(PCamDrv_Context camera_context);
EXTERN_C ECode SensorSetBrightness(int Brightness);
EXTERN_C ECode SensorSetContrast(int Contrast);
EXTERN_C ECode SensorSetSharpness(int Sharpness);
EXTERN_C ECode SensorSetColorMode(int ColorMode);
EXTERN_C ECode SensorSetSceneMode(int SceneMode);
EXTERN_C ECode SensorGetAppResolution(PCamDrv_Context pCameraCxt,
                 int PhotoResolution);
EXTERN_C ECode SensorGetDrvResolution(PCamDrv_Context pCameraCxt,
                 int AppPhotoResolution, int zoom);
EXTERN_C ECode SensorChangeResolution(PCamDrv_Context pCameraCxt,
                 int AppPhotoResolution, int zoom);
EXTERN_C ECode SensorSetDigitalZoom(int zoom);
EXTERN_C ECode SensorAdjustImage();
EXTERN_C void SensorBeforeStillCapture();
EXTERN_C void SensorAfterStillCapture();

// GPIO Functions
EXTERN_C void GpioSetup();
EXTERN_C void GpioCloseCamera();
EXTERN_C void GpioOpenFlash();
EXTERN_C void GpioCloseFlash();

// Ipp Functions
EXTERN_C ECode IppYCbCr422ResizeCopy(
    unsigned char * pYSrc, unsigned char * pCbSrc, unsigned char * pCrSrc,
    unsigned char * pYDst,  unsigned char * pCbDst, unsigned char * pCrDst,
    int srcWidth, int srcHeight,
    int dstWidth, int dstHeight);

#endif//__CCAMERA_H__
